package com.samoilovich.belarustoday.calendar.fragments;

import hirondelle.date4j.DateTime;

import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.samoilovich.belarustoday.R;

public class CalendarGridAdapter extends BaseAdapter {
    protected ArrayList<DateTime> mDatetimeList;
    protected int mMonth;
    protected int mYear;
    protected Context mContext;
    protected ArrayList<DateTime> disableDates;
    protected ArrayList<DateTime> mSelectedDates;
    private int mOtherMonthDateTimeColor, mDisableColor;

    // Use internally, to make the search for date faster instead of using
    // indexOf methods on ArrayList
    protected HashMap<DateTime, Integer> disableDatesMap = new HashMap<DateTime, Integer>();
    protected HashMap<DateTime, Integer> mSelectedDatesMap = new HashMap<DateTime, Integer>();

    protected DateTime mMinDateTime;
    protected DateTime mMaxDateTime;
    protected DateTime mToday;
    protected int mStartDayOfWeek;
    protected boolean mSixWeeksInCalendar;
    protected Resources Resources;
    protected DateTime mClickDate;

    /**
     * mData belongs to Calendar
     */
    protected HashMap<String, Object> mData;
    /**
     * extraData belongs to client
     */
    protected HashMap<String, Object> extraData;

    public void setAdapterDateTime(DateTime dateTime) {
        mMonth = dateTime.getMonth();
        mYear = dateTime.getYear();
        mDatetimeList = CalendarHelper.getFullWeeks(this.mMonth, this.mYear, mStartDayOfWeek, mSixWeeksInCalendar);
    }

    // GETTERS AND SETTERS
    public ArrayList<DateTime> getDatetimeList() {
        return mDatetimeList;
    }

    public DateTime getMinDateTime() {
        return mMinDateTime;
    }

    public void setMinDateTime(DateTime minDateTime) {
        this.mMinDateTime = minDateTime;
    }

    public DateTime getMaxDateTime() {
        return mMaxDateTime;
    }

    public void setMaxDateTime(DateTime maxDateTime) {
        this.mMaxDateTime = maxDateTime;
    }

    public ArrayList<DateTime> getDisableDates() {
        return disableDates;
    }

    public void setDisableDates(ArrayList<DateTime> disableDates) {
        this.disableDates = disableDates;
    }

    public ArrayList<DateTime> getSelectedDates() {
        return mSelectedDates;
    }

    public void setSelectedDates(ArrayList<DateTime> selectedDates) {
        this.mSelectedDates = selectedDates;
    }

    public HashMap<String, Object> getData() {
        return mData;
    }

    public void setData(HashMap<String, Object> data) {
        this.mData = data;
        // Reset parameters
        populateFromCalendarData();
    }

    public HashMap<String, Object> getExtraData() {
        return extraData;
    }

    public void setExtraData(HashMap<String, Object> extraData) {
        this.extraData = extraData;
    }

    public CalendarGridAdapter(Context context, int month, int year, HashMap<String, Object> mData, HashMap<String, Object> extraData) {
        super();
        this.mMonth = month;
        this.mYear = year;
        this.mContext = context;
        this.mData = mData;
        this.extraData = extraData;
        this.Resources = context.getResources();
        mOtherMonthDateTimeColor = context.getResources().getColor(R.color.calendar_dark_gray);
        mDisableColor = context.getResources().getColor(R.color.calendar_disable_gray);
        populateFromCalendarData();
    }

    /**
     * Retrieve internal parameters from caldroid data
     */
    @SuppressWarnings("unchecked")
    private void populateFromCalendarData() {
        disableDates = (ArrayList<DateTime>) mData.get(ScheduleCalendarFragment.DISABLE_DATES);
        if (disableDates != null) {
            disableDatesMap.clear();
            for (DateTime dateTime : disableDates) {
                disableDatesMap.put(dateTime, 1);
            }
        }
        mSelectedDates = (ArrayList<DateTime>) mData.get(ScheduleCalendarFragment.SELECTED_DATES);
        if (mSelectedDates != null) {
            mSelectedDatesMap.clear();
            for (DateTime dateTime : mSelectedDates) {
                mSelectedDatesMap.put(dateTime, 1);
            }
        }
        mClickDate = (DateTime) mData.get(ScheduleCalendarFragment.CLICKED_DATE);
        mMinDateTime = (DateTime) mData.get(ScheduleCalendarFragment._MIN_DATE_TIME);
        mMaxDateTime = (DateTime) mData.get(ScheduleCalendarFragment._MAX_DATE_TIME);
        mStartDayOfWeek = (Integer) mData.get(ScheduleCalendarFragment.START_DAY_OF_WEEK);
        mSixWeeksInCalendar = (Boolean) mData.get(ScheduleCalendarFragment.SIX_WEEKS_IN_CALENDAR);
        mDatetimeList = CalendarHelper.getFullWeeks(this.mMonth, this.mYear, mStartDayOfWeek, mSixWeeksInCalendar);
    }

    protected DateTime getToday() {
        if (mToday == null) {
            mToday = CalendarHelper.getToday();
        }
        return mToday;
    }

    protected void customizeTextView(int position, TextView cellView) {
        DateTime dateTime = getItem(position);

        if (dateTime != null) {
            // Customize for selected dates
            if (dateTime.compareTo(mClickDate) == 0) {
                cellView.setClickable(true);
                if (dateTime.equals(getToday())) {
                    cellView.setBackgroundResource(R.drawable.today_red_border);
                } else {
                    cellView.setBackgroundResource(R.drawable.red_border);
                }
                cellView.setTextColor(Color.BLACK);
            } else {
                if (mSelectedDates != null && mSelectedDatesMap.containsKey(dateTime)) {
                    cellView.setBackgroundResource(R.drawable.green_border_bg_selector);
                    // Should set cellView as clickable because click on item handles by grid.
                    cellView.setClickable(false);
                    if (dateTime.getMonth() != mMonth) {
                        cellView.setTextColor(mOtherMonthDateTimeColor);
                    } else {
                        cellView.setTextColor(Color.BLACK);
                    }
                    if (dateTime.equals(getToday())) {
                        cellView.setBackgroundResource(R.drawable.today_bg_selector);
                        cellView.setTextColor(Color.BLACK);
                    }
                } else {
                    // Should set cellView as clickable. CellView doesn't handle click on it and nothing will do.
                    cellView.setClickable(true);
                    if (dateTime.getMonth() != mMonth) {
                        cellView.setTextColor(mOtherMonthDateTimeColor);
                        cellView.setBackgroundColor(mDisableColor);
                    } else {
                        cellView.setTextColor(Color.BLACK);
                        cellView.setBackgroundColor(Color.WHITE);
                    }
                }
            }
        }
        cellView.setText("" + dateTime.getDay());
    }

    @Override
    public int getCount() {
        if (mDatetimeList != null) {
            return mDatetimeList.size();
        } else {
            return 0;
        }
    }

    @Override
    public DateTime getItem(int position) {
        if (mDatetimeList != null && mDatetimeList.size() > position) {
            return mDatetimeList.get(position);
        }
        return null;
    }

    @Override
    public long getItemId(int id) {
        return id;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        TextView cellView = (TextView) convertView;

        if (convertView == null) {
            cellView = (TextView) inflater.inflate(R.layout.date_cell, null);
        }
        customizeTextView(position, cellView);

        return cellView;
    }

}
